/*
* ExpressionUtil.java
* Created on  202015/6/2 10:10
* 版本       修改时间          作者      修改内容
* V1.0.1    202015/6/2       panzhuowen    初始版本
*
*/

package com.infitecs.eyas.util;

import java.util.*;

/**
 * 类的描述信息
 *
 * @author panzhuowen
 * @version 1.0.1
 */
public class ExpressionUtil {
    public final static String BLANK_SPACE = " ";

    public static ExpressionUtil instance;

    public ExpressionUtil() {
    }

    /**
     * 静态封装，整个工程中只有一个实例
     *
     * @return 该类的对象
     */

    public static ExpressionUtil getInstance() {
        if (instance == null) {
            instance = new ExpressionUtil();
            return instance;
        }
        return instance;
    }

    /**
     * @param exp 传入公式
     * @return list公式中除去所有操作符号后的参数
     */
    private List<String> infixExpToPostExp(String exp) {
        List<String> postExp = new ArrayList<>();
        StringBuffer numBuffer = new StringBuffer();
        Stack<Character> opStack = new Stack<Character>();
        char ch;
        opStack.push('#');
        try {
            for (int i = 0; i < exp.length(); ) {
                ch = exp.charAt(i);
                switch (ch) {
                    case '+':
                    case '-':
                    case '*':
                    case '/':
                    case '^':
                        i++;
                        break;
                    case '(':
                        opStack.push(ch);
                        i++;
                        break;
                    case ')':
                        char c = opStack.pop();
                        while (c != '(') {
                            postExp.add("" + c);
                            c = opStack.pop();
                        }
                        i++;
                        break;
                    case '#':
                        i++;
                        break;
                    case ' ':
                    case '\t':
                        i++;
                        break;
                    default:
                        numBuffer.append(ch);
                        ch = exp.charAt(++i);
                        while ((ch <= 'Z' && ch >= 'A') || (ch <= '9' && ch >= '0')) {
                            numBuffer.append(ch);
                            ch = exp.charAt(++i);
                        }

                        postExp.add(numBuffer.toString());
                        numBuffer = new StringBuffer();

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return postExp;
    }

    /**
     * @param exp 传入公式
     * @return 公式参数
     */

    public String param(String exp) {
        exp = exp + "#";
        List<String> expOps = infixExpToPostExp(exp);
        if (null == expOps || expOps.size() == 0) {
            return "";
        }
        Set<String> returnParam = new HashSet<String>();
        StringBuffer stringBuffer = new StringBuffer();
        for (int j = 0; j < expOps.size(); j++) {
            boolean isLetter = false;
            boolean isDigit = false;
            for (int i = 0; i < expOps.get(j).length(); i++) {
                if (Character.isLetter(expOps.get(j).charAt(i))) {
                    if (expOps.get(j).toString().contains("LOG")) {
                        isLetter = false;
                    } else {
                        isLetter = true;
                    }
                }
                if (Character.isDigit(expOps.get(j).charAt(i))) {
                    isDigit = true;
                }
            }
            if (isLetter && isDigit) {
                returnParam.add(expOps.get(j));
            }
        }
        if (returnParam.isEmpty()) {
            return "";
        }
        for (String str : returnParam) {
            stringBuffer.append(str).append(',');
        }
        return stringBuffer.toString().substring(0, stringBuffer.toString().length() - 1);
    }

    public String trimExp(String exp) {
        StringBuffer buffer = new StringBuffer(exp);
        int _index = buffer.indexOf(BLANK_SPACE);
        while (_index != -1) {
            buffer.deleteCharAt(_index);
            _index = buffer.indexOf(BLANK_SPACE, _index);
        }
        return buffer.toString();
    }

    public List<String> getFormulaElement(String exp) {
        List<String> stringList = infixExpToPostExp(exp);
        stringList.remove(0);
        return stringList;
    }
}
